#include <QApplication>
#include <QElapsedTimer>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QTimer>
#include <QEventLoop>

#include "unifiedgamerenderer.h"
#include "incrementalgamestateparser.h"
#include "gamedatapool.h"
#include "directdatachannel.h"

/**
 * @brief 性能测试类
 * 
 * 用于验证优化后的多线程架构性能提升
 */
class PerformanceTest : public QObject
{
    Q_OBJECT

public:
    explicit PerformanceTest(QObject *parent = nullptr);
    
    /**
     * @brief 运行所有性能测试
     */
    void runAllTests();

private slots:
    /**
     * @brief 测试渲染性能
     */
    void testRenderingPerformance();
    
    /**
     * @brief 测试增量解析性能
     */
    void testIncrementalParsingPerformance();
    
    /**
     * @brief 测试对象池效率
     */
    void testObjectPoolEfficiency();
    
    /**
     * @brief 测试内存使用
     */
    void testMemoryUsage();

private:
    /**
     * @brief 创建测试用的游戏状态JSON
     */
    QJsonObject createTestGameState(int snakeLength, int foodCount, int frameNumber);
    
    /**
     * @brief 打印测试结果
     */
    void printTestResults(const QString &testName, qint64 elapsedTime, int iterations, const QString &additionalInfo = "");
};

PerformanceTest::PerformanceTest(QObject *parent)
    : QObject(parent)
{
    qDebug() << "PerformanceTest: 性能测试初始化";
}

void PerformanceTest::runAllTests()
{
    qDebug() << "\n=== 开始性能测试 ===\n";
    
    testObjectPoolEfficiency();
    testIncrementalParsingPerformance();
    testRenderingPerformance();
    testMemoryUsage();
    
    qDebug() << "\n=== 性能测试完成 ===\n";
}

void PerformanceTest::testRenderingPerformance()
{
    qDebug() << "--- 测试渲染性能 ---";
    
    UnifiedGameRenderer renderer;
    UnifiedGameRenderer::RenderConfig config;
    config.targetFPS = 60;
    config.enableEffects = true;
    config.enableInterpolation = true;
    config.renderSize = QSize(800, 600);
    
    renderer.startGame(GameMode::SinglePlayer, config);
    
    QElapsedTimer timer;
    timer.start();
    
    const int testFrames = 100;
    int processedFrames = 0;
    
    // 模拟100帧渲染
    for (int i = 0; i < testFrames; ++i) {
        QJsonObject gameState = createTestGameState(10 + i % 20, 5 + i % 10, i);
        renderer.updateGameState(gameState);
        
        // 等待一帧时间 (16ms for 60 FPS)
        QEventLoop loop;
        QTimer::singleShot(16, &loop, &QEventLoop::quit);
        loop.exec();
        
        processedFrames++;
    }
    
    qint64 elapsed = timer.elapsed();
    double avgFrameTime = double(elapsed) / testFrames;
    double theoreticalFPS = 1000.0 / avgFrameTime;
    
    renderer.stopGame();
    
    QString additionalInfo = QString("平均帧时间: %1ms, 理论FPS: %2")
                            .arg(QString::number(avgFrameTime, 'f', 2))
                            .arg(QString::number(theoreticalFPS, 'f', 1));
    
    printTestResults("渲染性能测试", elapsed, testFrames, additionalInfo);
    
    // 验证性能要求
    if (avgFrameTime < 20) {  // 应该小于20ms (50+ FPS)
        qDebug() << "✅ 渲染性能测试通过 (平均帧时间 < 20ms)";
    } else {
        qDebug() << "❌ 渲染性能测试失败 (平均帧时间 >= 20ms)";
    }
}

void PerformanceTest::testIncrementalParsingPerformance()
{
    qDebug() << "--- 测试增量解析性能 ---";
    
    IncrementalGameStateParser parser;
    
    QElapsedTimer timer;
    const int testIterations = 1000;
    
    // 测试完整解析性能（第一次）
    timer.start();
    QJsonObject firstState = createTestGameState(15, 8, 0);
    parser.parseGameStateIncremental(firstState);
    qint64 firstParseTime = timer.elapsed();
    
    // 测试增量解析性能
    timer.start();
    for (int i = 1; i < testIterations; ++i) {
        QJsonObject gameState = createTestGameState(15 + i % 5, 8 + i % 3, i);
        parser.parseGameStateIncremental(gameState);
    }
    qint64 incrementalParseTime = timer.elapsed();
    
    // 获取解析统计
    auto stats = parser.getParseStats();
    
    double avgIncrementalTime = double(incrementalParseTime) / (testIterations - 1);
    
    QString additionalInfo = QString("首次解析: %1ms, 平均增量解析: %2ms, 增量比例: %3%")
                            .arg(firstParseTime)
                            .arg(QString::number(avgIncrementalTime, 'f', 3))
                            .arg(QString::number(stats.incrementalRatio, 'f', 1));
    
    printTestResults("增量解析性能测试", incrementalParseTime, testIterations - 1, additionalInfo);
    
    // 验证性能要求
    if (avgIncrementalTime < 2.0) {  // 应该小于2ms
        qDebug() << "✅ 增量解析性能测试通过 (平均解析时间 < 2ms)";
    } else {
        qDebug() << "❌ 增量解析性能测试失败 (平均解析时间 >= 2ms)";
    }
    
    parser.printParseStats();
}

void PerformanceTest::testObjectPoolEfficiency()
{
    qDebug() << "--- 测试对象池效率 ---";
    
    GameDataPool* pool = GameDataPool::instance();
    
    QElapsedTimer timer;
    const int testIterations = 1000;
    
    // 预热对象池
    pool->warmup(20, 30, 25);
    
    // 测试对象池效率
    timer.start();
    
    QList<RenderReadyGameData*> dataList;
    QList<QList<QPoint>*> pointLists;
    QList<QJsonObject*> jsonObjects;
    
    // 获取对象
    for (int i = 0; i < testIterations; ++i) {
        dataList.append(pool->acquireGameData());
        pointLists.append(pool->acquirePointList());
        jsonObjects.append(pool->acquireJsonObject());
    }
    
    // 释放对象
    for (int i = 0; i < testIterations; ++i) {
        pool->releaseGameData(dataList[i]);
        pool->releasePointList(pointLists[i]);
        pool->releaseJsonObject(jsonObjects[i]);
    }
    
    qint64 elapsed = timer.elapsed();
    
    // 获取对象池统计
    auto stats = pool->getStats();
    
    double avgOperationTime = double(elapsed) / (testIterations * 6); // 3种对象 × 2种操作
    
    QString additionalInfo = QString("平均操作时间: %1ms, 内存减少: %2%")
                            .arg(QString::number(avgOperationTime, 'f', 4))
                            .arg(QString::number(stats.memoryReductionRatio, 'f', 1));
    
    printTestResults("对象池效率测试", elapsed, testIterations * 6, additionalInfo);
    
    // 验证性能要求
    if (avgOperationTime < 0.1) {  // 应该小于0.1ms
        qDebug() << "✅ 对象池效率测试通过 (平均操作时间 < 0.1ms)";
    } else {
        qDebug() << "❌ 对象池效率测试失败 (平均操作时间 >= 0.1ms)";
    }
    
    pool->printStats();
}

void PerformanceTest::testMemoryUsage()
{
    qDebug() << "--- 测试内存使用 ---";
    
    GameDataPool* pool = GameDataPool::instance();
    auto stats = pool->getStats();
    
    qDebug() << "对象池内存使用统计:";
    qDebug() << "  估算内存使用:" << stats.estimatedMemoryUsage << "字节";
    qDebug() << "  内存减少比例:" << QString::number(stats.memoryReductionRatio, 'f', 1) << "%";
    
    // 验证内存使用合理性
    if (stats.estimatedMemoryUsage < 1024 * 1024) {  // 应该小于1MB
        qDebug() << "✅ 内存使用测试通过 (< 1MB)";
    } else {
        qDebug() << "❌ 内存使用测试失败 (>= 1MB)";
    }
}

QJsonObject PerformanceTest::createTestGameState(int snakeLength, int foodCount, int frameNumber)
{
    QJsonObject gameState;
    gameState["type"] = "game_state_update";
    gameState["timestamp"] = QDateTime::currentMSecsSinceEpoch();
    
    QJsonObject data;
    
    // 创建蛇数据
    QJsonArray snakes;
    QJsonObject snake;
    snake["alive"] = true;
    snake["score"] = frameNumber * 10;
    snake["direction"] = frameNumber % 4;
    snake["length"] = snakeLength;
    snake["player_id"] = "test_player";
    
    QJsonArray body;
    for (int i = 0; i < snakeLength; ++i) {
        QJsonObject segment;
        segment["x"] = 10 + i;
        segment["y"] = 10;
        body.append(segment);
    }
    snake["body"] = body;
    snakes.append(snake);
    
    // 创建食物数据
    QJsonArray foods;
    for (int i = 0; i < foodCount; ++i) {
        QJsonObject food;
        food["object_type"] = "food";
        QJsonObject position;
        position["x"] = (frameNumber + i * 5) % 40;
        position["y"] = (frameNumber + i * 3) % 30;
        food["position"] = position;
        food["value"] = 1;
        foods.append(food);
    }
    
    // 创建游戏信息
    QJsonObject gameInfo;
    gameInfo["alive_players"] = 1;
    gameInfo["total_players"] = 1;
    gameInfo["speed_ms"] = 100;
    
    // 创建地图信息
    QJsonObject map;
    map["width"] = 40;
    map["height"] = 30;
    
    data["snakes"] = snakes;
    data["foods"] = foods;
    data["game_info"] = gameInfo;
    data["map"] = map;
    data["status"] = 1;
    
    gameState["data"] = data;
    
    return gameState;
}

void PerformanceTest::printTestResults(const QString &testName, qint64 elapsedTime, int iterations, const QString &additionalInfo)
{
    double avgTime = double(elapsedTime) / iterations;
    
    qDebug() << QString("%1 结果:").arg(testName);
    qDebug() << QString("  总时间: %1ms").arg(elapsedTime);
    qDebug() << QString("  迭代次数: %1").arg(iterations);
    qDebug() << QString("  平均时间: %1ms").arg(QString::number(avgTime, 'f', 3));
    
    if (!additionalInfo.isEmpty()) {
        qDebug() << QString("  %1").arg(additionalInfo);
    }
    
    qDebug() << "";
}

// 如果直接运行此文件作为测试程序
#ifdef PERFORMANCE_TEST_MAIN
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    PerformanceTest test;
    test.runAllTests();
    
    return 0;
}
#endif

#include "performancetest.moc"
